package wisp.game;

import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;

import wisp.dataObjects.Statistics;
import wisp.dataObjects.WispCharacter;
import wisp.gui.SkillBar;
import wisp.gui.SkillWindow;

import com.golden.gamedev.object.Timer;

public class Heirophant extends PlayerSprite{

	private static final long serialVersionUID = 1L;

	private Timer healTimer;
	private Timer espoirTimer;
	
	
	private boolean healOnCoolDown;
	private boolean espoirOnCoolDown;
	
	private int healSkillLevel;
	private int espoirSkillLevel;
	private int energyCadenceSkillLevel;
	
	public Heirophant(String name, MainGame game, BufferedImage[] images, double x, double y) {
		super(name, game, images, x, y);
		
		healTimer = new Timer(3000);
		healTimer.setActive(false);
		healOnCoolDown = false;
		healSkillLevel = 1; // dapat nde! ayusin later for leveling up effects
		
		espoirTimer = new Timer (10000);
		espoirTimer.setActive(false);
		espoirOnCoolDown = false;
		espoirSkillLevel = 1;
		
		healSkillLevel = 0;
		espoirSkillLevel = 0;
		energyCadenceSkillLevel = 0;
		
		//
		this.setSkillUpgradePoints(30);
		
	}
	
	public void update(long elapsedTime)
	{
		//enable skills in skill bar if it's already unlocked
		if(healSkillLevel>0){
			this.getSkillBar().btn1.setEnabled(true);
		}else
			this.getSkillBar().btn1.setEnabled(false);
		
		if(espoirSkillLevel>0){
			this.getSkillBar().btn2.setEnabled(true);
		}else
			this.getSkillBar().btn2.setEnabled(false);
		
		// enable|disable skill buttons depending on mana lol
		super.update(elapsedTime);
	}
	
	//SPRITE FRAME INFO
	//
	//
    public int[] getUpImages() {
        return new int[] {0,1,2};
    }
    public int[] getDownImages(){
        return new int[] {6,7,8};
    }
    public int[] getLeftImages(){
        return new int[] {9,10,11};
    }
    public int[] getRightImages(){
        return new int[] {3,4,5};
    }
    
    //ADDED//
    public int[] getUpFlinch(){
    	return new int[]{12,13,14};
    }
    
    public int[] getDownFlinch(){
    	return new int[]{18,19,20};    
    }
    
    public int[] getLeftFlinch(){
    	return new int[]{21,22,23};
    }
    
    public int[] getRightFlinch(){
    	return new int[]{15,16,17};
    }

    //END ADDED//
	
    ///////////added - for buff <TEMP VALUES! UPDATE PLZ>
    public int[] getUpBuffed(){
    	return new int[]{0,1,2};
    }
    public int[] getDownBuffed(){
    	return new int[]{6,7,8};
    }
    public int[] getLeftBuffed(){
    	return new int[]{9,10,11};
    }
    public int[] getRightBuffed(){
    	return new int[]{3,4,5};
    }
	
	private void performHealCDCheck(long elapsedTime)
	{
		if (healTimer.action(elapsedTime) == true)
		{
		      healTimer.setActive(false);
		      healOnCoolDown = false;
		}
		
	}

	private void performEspoirCDCheck(long elapsedTime)
	{
		if (espoirTimer.action(elapsedTime) == true)
		{
			espoirTimer.setActive(false);
			espoirOnCoolDown = false;
		}
		
	}
	
	/*************** MODIFIED *****************************/
	// skill commands are mapped here, instead of the main game class
	// skill bar sends commands here~
	// 
	@Override
	public void checkForSkillUse(long elapsedTime) {
		
		performHealCDCheck(elapsedTime);
		performEspoirCDCheck(elapsedTime);
		
		//Heal
		if (getGame().keyPressed(KeyEvent.VK_1)  || this.getSkillKeyUsed() == 1)
		{
			
			 if ( healOnCoolDown == false)
			 {
				 if (healSkillLevel != 0)
				 {
			       performSkill1();
			       this.setSkillKeyUsed(-1);
				 }
			 }
			 else
				 System.out.println ("cant use skill yet!");
		}
		
		if (getGame().keyPressed(KeyEvent.VK_2)  || this.getSkillKeyUsed() == 2)
		{
			if (espoirOnCoolDown == false)
			 {
				 if (espoirSkillLevel != 0)
				 {
			        performSkill2();
			        this.setSkillKeyUsed(-1);
				 }
			 }
			 else
				 System.out.println ("cant use skill yet!");
			
			    
		}
		if (getGame().keyPressed(KeyEvent.VK_3))
		{
			System.out.println ("bash daw*******");
			
			    performSkill3();
		} 
	}

	@Override
	//heal should be coded that accepts two kinds of target *monster/self and *other players
	public void performSkill1() {
	
		
		int healValue;
		if (this.getTarget() instanceof PlayerSprite)//verify kay sir sol
		{
			PlayerSprite healTarget = (PlayerSprite) this.getTarget();
			System.out.println ("Player's HP before heal: " + healTarget.getCurrentHP());
			healValue = computeHealValue ();
			healTarget.setCurrentHP (healValue + healTarget.getCurrentHP());
			System.out.println ("Player's HP after heal: " + healTarget.getCurrentHP());
			this.getGame().getParticleGroup().add(new HitSprite(this.getGame().getImages("IMAGES/Sprites/heal.png", 4, 1), healTarget.getX()+(healTarget.getWidth()/2), healTarget.getY()+(healTarget.getHeight()/2)));
		}
		
		else if (this.getTarget() instanceof MonsterSprite || this.getTarget() == null)
		{
			System.out.println ("Player's HP before heal: " + this.getCurrentHP());
			healValue = computeHealValue ();
			this.setCurrentHP (healValue + this.getCurrentHP());
			System.out.println ("Player's HP after heal: " + this.getCurrentHP());
			this.getGame().getParticleGroup().add(new HitSprite(this.getGame().getImages("IMAGES/Sprites/heal.png", 4, 1), getX(), getY()));
		}
		

		/************************************CHANGE IN BETWEEEN*****************************/
		this.setCurrentMP(new Double(this.getCurrentMP() - ( getMaxMP() * .03)).intValue());
		/************************************CHANGE IN BETWEEEN*****************************/
		
		
	}
	
	private double getHealBonusValue()
	{
		double bonus;
		switch (this.healSkillLevel)
		{
			case 1: bonus = 0.1; break;
			case 2: bonus = 0.11; break;
			case 3: bonus = 0.12; break;
			case 4: bonus = 0.13; break;
			case 5: bonus = 0.14; break;
			case 6: bonus = 0.15; break;
			case 7: bonus = 0.16; break;
			case 8: bonus = 0.17; break;
			case 9: bonus = 0.18; break;
			case 10: bonus = 0.2; break;
			default: bonus = -1;
		}
		return bonus;
	}
	
	private double getEspoirBonusValue()
	{
		double bonus;
		switch (this.espoirSkillLevel)
		{
			case 1: bonus = 0.01; break;
			case 2: bonus = 0.02; break;
			case 3: bonus = 0.03; break;
			case 4: bonus = 0.04; break;
			case 5: bonus = 0.05; break;
			case 6: bonus = 0.06; break;
			case 7: bonus = 0.07; break;
			case 8: bonus = 0.08; break;
			case 9: bonus = 0.09; break;
			case 10: bonus = 0.10; break;
			default: bonus = -1;
		}
		return bonus;
	}
	
	/************************************CHANGE IN BETWEEEN*****************************/
	private double getEspoirSPCost()
	{
		double bonus;
		switch (this.espoirSkillLevel)
		{
			case 1: bonus = 0.15; break;
			case 2: bonus = 0.14; break;
			case 3: bonus = 0.13; break;
			case 4: bonus = 0.12; break;
			case 5: bonus = 0.11; break;
			case 6: bonus = 0.1; break;
			case 7: bonus = 0.08; break;
			case 8: bonus = 0.06; break;
			case 9: bonus = 0.04; break;
			case 10: bonus = 0.2; break;
			default: bonus = -1;
		}
		return bonus;
	}
	/************************************CHANGE IN BETWEEEN*****************************/

	
	//kulang si skill level kasi wala pa -___-!!!
	private int computeHealValue() {
		
		WispCharacter wispcharacter;
		Statistics stats;
		double tempValue, tempValue2;
		
		wispcharacter = this.getWispcharacter();
		stats = this.getStatistics();
		
		int level = wispcharacter.getLevel();
		int statINT = stats.getCInt();
		int statSPR = stats.getSpr();
		
		tempValue = level /2;
		/************************************THIS NEEDS SOME CHANGING PERO DI KO PA BINAGO*****************************/
		tempValue2 = statINT/ statSPR; // problematic causes Arithmetic exception >.<
		
		tempValue = tempValue * healSkillLevel * tempValue2;
		
		//hardcoded pero later gawa ng method for different skill levels ng heal
		tempValue = tempValue + (tempValue * getHealBonusValue()) + 1;
		
		return (new Double(tempValue).intValue()); //final heal value!
	}


	@Override
	public void performSkill2() {
		// TODO Auto-generated method stub
		if (this.getTarget() instanceof PlayerSprite)//verify kay sir sol
		{
			PlayerSprite espoirTarget = (PlayerSprite)this.getTarget();
		
			espoirTarget.setCurrentHP(this.getCurrentHP() + new Double(espoirTarget.getCurrentHP() * getEspoirBonusValue()).intValue()); 

			this.getGame().getParticleGroup().add(new HitSprite(this.getGame().getImages("IMAGES/Sprites/espoir.png", 4, 1), getX(), getY()));
		}
		else if (this.getTarget() instanceof MonsterSprite || this.getTarget() == null)
		{
			//kasi si hp nababawasan ng malupet kasi mali ung unang formula ROFL
			this.setCurrentHP(this.getCurrentHP() + new Double(this.getCurrentHP() * getEspoirBonusValue()).intValue()); 
		
			this.setCurrentMP(new Double(this.getCurrentMP() - ( this.getCurrentMP() * getEspoirSPCost())).intValue());
			this.getGame().getParticleGroup().add(new HitSprite(this.getGame().getImages("IMAGES/Sprites/espoir.png", 4, 1), getX(), getY()));
		}
		
		this.setCurrentMP(new Double(this.getCurrentMP() - ( this.getMaxMP() * getEspoirSPCost())).intValue());
		
	}

	@Override
	public void performSkill3() {
		// TODO Auto-generated method stub
		
	}

	public int getHealSkillLevel() {
		return healSkillLevel;
	}

	public void setHealSkillLevel(int healSkillLevel) {
		this.healSkillLevel = healSkillLevel;
	}
	
	public void checkIfLevelUp(int exp)
	{
		super.checkIfLevelUp(exp);
		//this.setStatistics(this.getLevelInfo().getNewHeirophantStatistics(this.getLevel()));
	}
	
	public void configSkillbar(SkillBar s){
		this.setSkillBar(s);
		
		this.getSkillBar().btn1.setText("Heal 0");
		this.getSkillBar().btn2.setText("Espoir 0");
		
		this.getSkillBar().btn3.setText("EnCad 0");
		this.getSkillBar().btn3.setEnabled(false);
	}
	
	public void configSkillWindow(SkillWindow s){
		s.setSkill1("Heal", "Share your love!", 0, (new Double( getMaxMP() * .03).intValue()), 0);
		s.setSkill2("Espoir", "Cleanse them of ailments!", 0, (new Double( this.getMaxMP() * getEspoirSPCost()).intValue()), 0);
		s.setSkill3("Energy Cadence", "Allows you to rest better~", 0, 0, 0);
		
		this.setSkillWindow(s);
	}
	
	public void increaseSkill1(){
		
		healSkillLevel++;
		System.out.println("[PLAYER] Heal level increased to " + healSkillLevel);
		
		this.setSkillUpgradePoints(this.getSkillUpgradePoints()-1);
		
		//UPDATE skillwindow info if nescessary~
		this.getSkillWindow().sk1sLevel.setText(((Integer)healSkillLevel).toString());
		this.getSkillBar().btn1.setText("Heal " + this.healSkillLevel);
	}
	
	public void increaseSkill2(){
		
		espoirSkillLevel++;
		System.out.println("[PLAYER] Espoir level increased to " + espoirSkillLevel);
		
		this.setSkillUpgradePoints(this.getSkillUpgradePoints()-1);
		
		//UPDATE skillwindow info if nescessary~
		this.getSkillWindow().sk2sLevel.setText(((Integer)espoirSkillLevel).toString());
		this.getSkillBar().btn2.setText("Espoir " + this.espoirSkillLevel);
		
		
	}
	
	public void increaseSkill3(){
		int bonusRegen;
		double bonusMP;
		
		bonusRegen = 0;
		bonusMP = 0;
		
		
			energyCadenceSkillLevel++;
			
			switch (energyCadenceSkillLevel) {
			case 1: {		
				bonusMP = 0.05;
				bonusRegen = 2;
			}break;
			case 2: {
				bonusMP = 0.06;
				bonusRegen = 3;	
			}break;
			case 3: {
				bonusMP = 0.07;
				bonusRegen = 4;
			}break;
			case 4: {
				bonusMP = 0.08;
				bonusRegen = 5;
			}break;
			case 5: {
				bonusMP = 0.09;
				bonusRegen = 6;
			}break;
			case 6: {
				bonusMP = 0.12;
				bonusRegen = 7;
			}break;
			case 7: {
				bonusMP = 0.14;
				bonusRegen = 8;
			}break;
			case 8: {
				bonusMP = 0.16;
				bonusRegen = 9;
			}break;
			case 9: {
				bonusMP = 0.18;
				bonusRegen = 10;
			}break;
			case 10: {
				bonusRegen = 20;
				bonusMP = 12;
			}break;

			default:
				break;
			}
			
			//increase max mp & regen rate (lol not following the formula for now... di percent)
			
			//set regen rate~
			this.getStatistics().setMpGR(getStatistics().getMpGR() + bonusRegen);
			
			//compute for the bonus mp
			int bMP = ((Double)(getWispcharacter().getMMP() * bonusMP)).intValue();
			//increase mp~
			this.getWispcharacter().setMMP(getWispcharacter().getMMP() + bMP);
			this.setMaxMP(this.getWispcharacter().getMMP());
			this.setCurrentMP(getCurrentMP() + bMP);
			
			System.out.println("[PLAYER] Energy Cadence level increased to " + energyCadenceSkillLevel);
			
			this.setSkillUpgradePoints(this.getSkillUpgradePoints()-1);
			
			//updating stuff...
			this.getSkillWindow().sk3sLevel.setText(((Integer)energyCadenceSkillLevel).toString());
			
			this.getSkillBar().btn3.setText("EnCad " + this.energyCadenceSkillLevel);
	}
	
	public int get1stSkillLevel(){
		return healSkillLevel;
	}
	public int get2ndSkillLevel(){
		return espoirSkillLevel;
	}
	public int get3rdSkillLevel(){
		return energyCadenceSkillLevel;
	}

}
